ReverseSequence ================= 对输入序列进行部分反转。 输入: - **src** - 需反转数据的地址 - **seq_lengths** - 指定反转长度,为一维向量。 - **param** - 算子计算所需参数的结构体。其各成员见下述。 - **core_mask** - 核掩码。 **ReverseSequenceParameter定义:** .. code-block:: c :linenos: typedef struct ReverseSequenceParameter { int* shape_; // 输入和输出张量的形状 int* strides_; // 一个记录张量每一维步长的数组 int seq_dim_; // 指定反转的维度 int batch_dim_; // 指定切片维度 int ndim_; // 输入和输出张量的维度 int type_size_; // 输入和输出张量数据类型的长度 int copy_elem_num_; // 在inner_count循环中一次应被拷贝的元素数目 int outer_stride_; // 外层元素间的步长 int outer_count_; // 外层元素数 int inner_stride_; // 内层元素间的步长 int inner_count_; // 内层元素数 } ReverseSequenceParameter; 输出: - **dst** - 输出地址。 支持平台: ``FT78NE`` ``MT7004`` .. note:: - FT78NE 支持int8, int16, int32, fp32, fp64, cplx64, cplx128 - MT7004 支持fp16, fp32, int16, int32, cplx64 **共享/私有存储版本:** .. c:function:: void anytype_reverse_sequence_anycore(void* src, void* dst, int* seq_lengths, ReverseSequenceParameter* param, int core_mask) 各种数据类型、私有及共享空间版本均使用该函数。对于不同数据类型,改变param中的type_size_参数即可。 **C调用示例:** .. code-block:: c :linenos: :emphasize-lines: 41 void Resize(ReverseSequenceParameter* param) { param->strides_ = (int*)0xA8020000; ComputeStrides(param->shape_, param->strides_, param->ndim_); int less_dim = param->batch_dim_ > param->seq_dim_ ? param->seq_dim_ : param->batch_dim_; int greater_dim = param->batch_dim_ < param->seq_dim_ ? param->seq_dim_ : param->batch_dim_; // calculate the size of elements should be copied at one time param->copy_elem_num_ = CountElementAfterDim(param->shape_, greater_dim, param->ndim_); // calculate the number of elements before the less axis and the stride param->outer_count_ = CountElementBeforeDim(param->shape_, less_dim); param->outer_stride_ = param->shape_[less_dim] * CountElementAfterDim(param->shape_, less_dim, param->ndim_); // calculate the number of elements between the less axis and the greater axis and the stride param->inner_count_ = 1; int i; for (i = less_dim + 1; i < greater_dim; i++) { param->inner_count_ *= param->shape_[i]; } param->inner_stride_ = param->shape_[greater_dim] * CountElementAfterDim(param->shape_, greater_dim, param->ndim_); } void TestReverseSequenceFp32(int* shape, int* orig_seq_lengths, int seq_dim, int batch_dim, int ndim, int core_mask) { int core_id = get_core_id(); int core_num = GetCoreNum(core_mask); int logic_core_id = GetLogicCoreId(core_mask, core_id); float* input_data = (float*)0x88000000; // 测试私有空间时地址设置在私有空间内即可 float* output_data = (float*)0x98000000; float* check = (float*)0xB8000000; int* seq_lengths = (int*)0xC8000000; ReverseSequenceParameter* param = (ReverseSequenceParameter*)0xA8000000; int i; if (logic_core_id == 0) { param->shape_ = (int*)0xA8010000; memcpy(param->shape_, shape, sizeof(int) * ndim); memcpy(seq_lengths, orig_seq_lengths, sizeof(int) * shape[batch_dim]); param->batch_dim_ = batch_dim; param->seq_dim_ = seq_dim; param->ndim_ = ndim; param->type_size_ = sizeof(float); Resize(param); } sys_bar(0, core_num); // 初始化参数完成后进行同步 anytype_reverse_sequence_anycore(input_data, output_data, seq_lengths, param, core_mask); } void main(){ int shape[3] = {3, 4, 10}; int seq_lengths[3] = {1, 2, 3}; int ndim = 3; int seq_dim = 1; int batch_dim = 0; int core_mask = 0b1111; // 测试单核时核掩码设置为0b0001即可 TestReverseSequenceFp32(shape, seq_lengths, seq_dim, batch_dim, ndim, core_mask); }